/**********************************************************************************
**
** Copyright (C) 1994 Narvik University College
** Contact: GMlib Online Portal at http://episteme.hin.no
**
** This file is part of the Geometric Modeling Library, GMlib.
**
** GMlib is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** GMlib is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with GMlib.  If not, see <http://www.gnu.org/licenses/>.
**
**********************************************************************************/



/*! \file gmPFolium.c
 *
 *  Implementation of the PFolium template class.
 *
 *  \date   2008-09-10
 */


namespace GMlib {


  template <typename T>
  inline
  PFolium<T>::PFolium( T size ) {

    _size = size;
    this->_dm = GM_DERIVATION_EXPLICIT;
  }


  template <typename T>
  inline
  PFolium<T>::PFolium( const PFolium<T>& copy ) : PCurve<T>( copy ) {}


  template <typename T>
  PFolium<T>::~PFolium() {}


  template <typename T>
  inline
  void PFolium<T>::eval( T t, int d, bool /*l*/ ) {

    this->_p.setDim( d + 1 );

    T a=2;
    T b = 4;
    T r = cos(t)*(4*a*sin(t)*sin(t)-b);
    this->_p[0][0] = (T) _size * r*cos(t);
		this->_p[0][1] = (T) _size * r*sin(t);
		this->_p[0][2] = T(0);

    if( this->_dm == GM_DERIVATION_EXPLICIT ) {

      if( d > 0 ) {
				this->_p[1][0] = (T) _size * (-4*a*sin(t)*sin(t)*sin(t)*sin(t)+(12*a*cos(t)*cos(t)+b)*sin(t)*sin(t)-b*cos(t)*cos(t));
        this->_p[1][1] = (T) _size * 8*a*cos(t)*cos(t)*cos(t)*sin(t)*_size-2*cos(t)*sin(t)*(4*a*sin(t)*sin(t)-b);
        this->_p[1][2] = T(0);
      }


      if( d > 1 ) {

        this->_p[2][0] = (T)0;
        this->_p[2][1] = (T)0;
        this->_p[2][2] = T(0);
      }
    }
  }


  template <typename T>
  inline
  T PFolium<T>::getEndP() {

    return T( M_PI * 2.0 );
  }


  template <typename T>
  inline
  std::string PFolium<T>::getIdentity() const {

    return "PFolium";
  }


  template <typename T>
  inline
  T PFolium<T>::getStartP() {

    return T(0);
  }


  template <typename T>
  inline
  bool PFolium<T>::isClosed() const {

    return true;
  }
}
